// JavaScript Document

function TreeNode(value, parent) {
	this.value = value;	
	this.children = new Array();
	this.level = 0;
	this.parent = parent;
	if(parent != null) {
		parent.addChild(this);
	}
	this.tag = null;

	TreeNode.prototype.addChild = function(child, index) {
		if(index == null) {
			index = this.children.length;
		}
		this.children.splice(index, 0,  child);
		child.level = this.level + 1;
		child.parent = this;
	}
	
	TreeNode.prototype.removeChild = function(child) {
		for(var i=0; i<this.children.length; ++i) {
			if(this.children[i] == child) {
				child.level = 0;
				child.parent = null;
				this.children.splice(i, 1);				
				break;
			}
		}
	}
	
	TreeNode.prototype.removeChildAt = function(index) {
		if(index >= 0 && index < this.children.length) {
			this.children[index].level = 0;
			this.children[index].parent = null;
			this.children.splice(index, 1);
		}
	}
	
	TreeNode.prototype.removeChildren = function() {
		while(this.children.length > 0) {
			var c = this.children[0];
			c.level = 0;
			c.parent = null;
			this.children.splice(0, 1);			
		}
	}
	
	TreeNode.prototype.toString = function() {
		return "TreeNode (level = "+this.level+", value = "+this.value+", number of children = "+this.children.length+")";
	}
}

function Tree(root, rootTag, kindergarten, getTagByNode) {
	this.root = root;	
	this.root.tag = rootTag;
	if(kindergarten == null) {
		kindergarten = -1;
	}
	if(getTagByNode != null) {
		this.getTagByNode = getTagByNode;
	} else {
		this.getTagByNode = function(node) {
			return Node("div", new Array("style", "padding-left:"+(node.level * 20)+"px; border-left: thin dashed #000;"), node.value);	
		}
	}
	
	Tree.prototype.show = function() {		
		var nodes = new Array(this.root);
		while(nodes.length > 0) {
			var n = nodes.pop();
			for(var i=0; i<n.children.length; ++i) {
				var child = n.children[i];
				if(child.tag == null) {
					var newTag = this.getTagByNode(child);
					if(n.tag.children[kindergarten] != undefined) {
						n.tag.children[kindergarten].appendChild(newTag);
					} else {
						n.tag.appendChild(newTag);
					}
					child.tag = newTag;
					nodes.push(n);
					nodes.push(child);
					break;
				}
			}
		}
	}
}